package com.zx.framework.core.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.zx.framework.core.exception.ServiceException;

/**
 * 用于生成有规律的编号
 * @author stylewolf
 *
 */
public class SerialUtil {
	
	private static final Logger LOGGER = Logger.getLogger(SerialUtil.class);
	private static final String START = "start";
	private static final String MAX = "max";
	private static final String CURRENT = "current";
	/**
	 * 
	 * @param preSuff 序列号前缀
	 * @param size 个数
	 * @param path 路径
	 * @param suff 文件名
	 */
	@Deprecated
	public synchronized static void create(String preSuff,int size,String path){
		File dataFile = new File(path);
		try {
			if(!dataFile.exists()){
				dataFile.getParentFile().mkdirs();
				dataFile.createNewFile();
			}else{
				return;
			}
		} catch (IOException e) {
			throw new ServiceException(e);
		}
		String length = ((size +"").length())+"";
		ObjectOutputStream oos =null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream(dataFile));
			List<String> nos = new ArrayList<String>();
			for (int i = 0; i < size; i++) {
				nos.add(preSuff+String.format("%0"+length+"d",i));
			}
			oos.writeObject(nos);
		} catch (FileNotFoundException e) {
			throw new ServiceException(e);
		} catch (IOException e) {
			throw new ServiceException(e);
		}
		finally{
			if(ObjectUtils.isNotNull(oos)){
				try {
					oos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	@Deprecated
	public static synchronized String getSno(String filePath){
		ObjectInputStream ois = null;
		ObjectOutputStream oos =null;
		String rs = null;
		List<String> nos =  null;
		try {
			ois = new ObjectInputStream(new FileInputStream(filePath));
			nos = (ArrayList<String>) ois.readObject();
			if(nos.isEmpty()){
				throw new ServiceException("编号已用尽！");
			}
			rs = nos.remove(0);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new ServiceException("未找到数据文件！");
		} catch (IOException e) {
			e.printStackTrace();
			throw new ServiceException("未找到数据文件！");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new ServiceException("数据文件已损毁！");
		}finally{
			if(ObjectUtils.isNotNull(ois)){
				try {
					ois.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		try {
			oos = new ObjectOutputStream(new FileOutputStream(filePath));
			oos.writeObject(nos);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new ServiceException("未找到数据文件！");
		} catch (IOException e) {
			e.printStackTrace();
			throw new ServiceException("未找到数据文件！");
		}finally{
			if(ObjectUtils.isNotNull(oos)){
				try {
					oos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(ObjectUtils.isNotNull(ois)){
				try {
					ois.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return rs;
	}
	/**
	 * 生成连续编号，并保存至指定路径
	 * @param max 最大编号
	 * @param start 编号开始
	 * @param path 存储路径
	 */
	public synchronized static void create(int max,int start,String path){
		try {
			File file = new File(path);
			if(!file.exists()){
				file.getParentFile().mkdirs();
				file.createNewFile();
			}else{
				return;
			}
			//保存序列号信息
			Map<String, Integer> map = new HashMap<String, Integer>();
			map.put(START, start);
			map.put(MAX, max);
			map.put(CURRENT, start);
			StreamUtil.writeObjectForFile(map, path);
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error("", e);
			throw new ServiceException("创建数据文件失败！");
		}
	}
	/**
	 * 获取编号
	 * @param suff 返回需要添加的前缀
	 * @param filePath 文件地址
	 * @return
	 */
	public static synchronized String getSerial(String suff,String filePath){
		try {
			Map<String,Integer> map = StreamUtil.readObjectForFile(filePath);
			int max = map.get(MAX);
			int current = map.get(CURRENT);
			
			//编号超出
			if(current>max){
				throw new ServiceException("编号已用尽！");
			}
			int next = current+1;
			map.put(CURRENT, next);
			StreamUtil.writeObjectForFile(map, filePath);
			String length = (max +"").length()+"";
			return suff+String.format("%0"+length+"d",current);
		} catch (Exception e) {
			LOGGER.error("", e);
			throw new ServiceException("获取编号失败！"+e.getMessage());
		}
	}
	public static void main(String[] args) {
		final String preSuff = DatetimeUtils.dateToString(new Date(), "yyMMdd");
//		create(preSuff,20000,"f:/test1/pass.sno");
//		
//		for (int i = 0; i < 100; i++) {
//			new Thread(new Runnable() {
//				
//				@Override
//				public void run() {
//					System.out.println(getSno("f:/test1/pass.sno"));
//				}
//			}).start();
//		}
		
		create(10000, 1, "e:/test1/20151014.sno");
		
		for (int i = 0; i < 2; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					System.out.println(getSerial(preSuff,"e:/test/test.sno"));
				}
			}).start();
		}
	}
}
